/*
	Copyright (c) 2011, kaixin001 Inc. All rights reserved.
	http://www.kaixin001.com
	author: minliang@corp.kaixin001.com
*/

/**
 * @class Panel 最基础的浮动层功能封装
 * @singleton
 */
define('core/panel/Panel', ['jQuery'], function( require ){
	var $ = require('jQuery'),
		mix = K.mix,
		UA = K.Browser,
		CustEvent = K.CustEvent,
		IFRAME_SRC = 'http://' + K.Env.KX_HOST + '/interface/diablank.php',
		zIndex = 950000;

	function Panel(opts){
		this.PANEL_CLASS = 'panel';
		this.IFRAME_CLASS = 'panel-iframe';
		this.INNER_CLASS = 'panel-content';
		this.atCenter = true;
		//延迟显示的时间(毫秒)
		this.delay = 300;
		//点击Panel之外关闭Panel
		this.useBlurClose = false;

		mix( this, opts );

		this.useIframe =
            ( 'useIframe' in this ) ?
                this.useIframe :
                this._needIframe();

		this.top = this.top || 0;
		this.left = this.left || 0;

		CustEvent.createEvents(this,
            'beforeinit,afterinit,beforeshow,aftershow,beforehide,afterhide,beforedispose,afterdispose');

		this.fire('beforeinit');
		this._init();
		this.fire('afterinit');
	}
	mix(Panel.prototype,{
		_init: function(){
			this._createPanelBox();
			this._bindPanelEvents();
			this.visible = this.isPanelShow();
		},
		/**
		 * 创建一个容器元素
		 *
		 * @method
		 * @protected
		 * @param void
		 * @return {Panel object}
		 */
		_createPanelBox: function() {
			this._panel = $('<div class="' + this.PANEL_CLASS + '"></div>');
			this._content = $('<div class="' + this.INNER_CLASS + '"></div>');
			this._panel.append(this._content);

			if ( this.useIframe ){
				this._createIframe();
			}
			this._panel.appendTo($('body'));

			var rect = {
				left:	this.left,
				top:	this.top
			};

			if( !isNaN( this.width ) ){
				rect.width = this.width;
			}

			if( !isNaN( this.height ) ){
				rect.height = this.height;
			}

			this.setRect( rect );
			this._panel.hide();

			this.noBlurList = [ this._panel[0] ];

		},
		_createIframe: function(){
			this._iframe = $( '<iframe class="' + this.IFRAME_CLASS + '" frameborder="0" src="about:blank"></iframe>' );
			this._iframe.css( 'width','100%' ).css( 'height','100%' );
			this._panel.append( this._iframe );
		},
		/**
		 * 检测自动生成iframe条件
		 *
		 * @method
		 * @protected
		 * @param void
		 * @return {bool}
		 */
		_needIframe: function () {
			var useIframe = ( UA.ie && parseInt( UA.ie, 10 ) < 7 )
							&&
							( document.getElementsByTagName('select').length
							  || document.getElementsByTagName('object').length
							);
			return useIframe;
		},
		/**
		 * 检测使用position fixed的条件
		 *
		 * @method
		 * @protected
		 * @param void
		 * @protected
		 * @return {bool}
		 */
		_canbeFixed: function () {
			return !UA.ie || (UA.ie && UA.ie > 6);
		},
		/**
		 * 绑定事件
		 *
		 * @method
		 * @protected
		 * @param void
		 * @protected
		 */
		_bindPanelEvents: function(){
			var ins = this;
			//Panel Blur时关闭
			if( this.useBlurClose ){
				$( document ).bind( 'mousedown', { ins: this }, this._blurListener );
			}
		},
		/**
		 * 失焦响应
		 *
		 * @method
		 * @protected
		 * @param void
		 * @protected
		 */
		_blurListener: function(e){
			var target = e.target,
				ins = e.data.ins,
				panelEl = ins._panel[0];

			if( ins.visible && ins.isTriggerBlur( target ) ){
				ins.hide();
			}

		},
		/**
		 * 清除事件
		 *
		 * @method
		 * @protected
		 * @param void
		 * @protected
		 */
		_clearPanelEvents: function(){
			var ins = this;
			//Panel Blur时关闭
			if( this.useBlurClose ){
				$( document ).unbind( 'mousedown', this._blurListener );
			}

            this._panel.unbind();
		},
		/**
		 * 元素的鼠标事件是否触发窗口Blur
		 *
		 * @method
		 * @protected
		 * @param void
		 * @protected
		 */
		isTriggerBlur: function( target ){
			var panelEl = this._panel[0],
				isInNoBlurList = false;

			K.forEach( this.noBlurList, function( el ){
				if( el == target || $.contains( el, target ) ){
					isInNoBlurList = true;
				}
			});

				//包含在Panel之内
			if( $.contains( panelEl, target )
				//如果在例外列表
				|| isInNoBlurList) {
				return false;
			}
			else{
				return true;
			}
		},
		/**
		 * 显示Panel控件
		 *
		 * @method show
		 * @param {number} top 坐标
		 * @param {number} left 坐标
		 * @param {number} width 宽度
		 * @param {number} height 高度
		 * @param {HTMLElement} el 参考元素(如果未提供参考元素则上述坐标信息参考document,否则参考该元素)
		 */
		show: function( rect , el ){
			//只提供el，则Panel的位置与el的左上角对齐
			if( arguments.length == 1 && !$.isPlainObject( rect ) ){
				el = rect;
				rect = {
					top: 0,
					left: 0
				};
			}
			if( el ){
				el = $(el);
				var elOffset = el.offset();
				rect.top	+= elOffset.top;
				rect.left	+= elOffset.left;
			}
			if( rect ){
				this.setRect( rect );
			}

			this.fire('beforeshow');
			this._panel.data('obj', this);
			this._panel.css('z-index', zIndex++);
			this._panel.show();

			if( this.atCenter ){
				this.center();
			}

			this.visible = true;
			this.fire('aftershow');
			return this;
		},
		hide: function(){
			this.fire('beforehide');
			this._panel.hide();
			this._clearTimer();
			this.visible = false;
			this.fire('afterhide');
			return this;
		},
		/**
		 * 延迟一定时间显示Panel
		 */
		delayShow: function(){
			var ins = this,
				args = arguments;
			this._clearTimer();
			this._delayTimer = setTimeout( function(){
				ins._delayTimer = null;
				ins.show( args );
			}, this.delay );
		},
		_clearTimer: function(){
			if( this._delayTimer ){
				clearTimeout( this._delayTimer );
			}
		},
		/**
		 * 设置Panel的坐标和尺寸
		 *
		 * @method setRect
		 * @param  {number} left	坐标
		 * @param  {number} top		坐标
		 * @param  {number} width	宽度
		 * @param  {number} height	高度
		 */
		setRect: function( rect ){
			var w = rect.width	,
				h = rect.height ;

			this._panel.offset(rect);
			if( typeof( w ) != 'undefined' ){
				this._panel.width( w );
			}
			if( typeof( h ) != 'undefined' ){
				this._panel.height( h );
			}
			return this;
		},
		/**
		 * 设置Panel的尺寸
		 *
		 * @method setSize
		 * @param  {number} w宽度
		 * @param  {number} h高度
		 * @return {Panel object}
		 */
		setSize: function( w, h ){
			this._panel.width( w ).height( h );
			return this;
		},
		/**
		 * 设置Panel的坐标
		 *
		 * @method setXY
		 * @param  {number} w宽度
		 * @param  {number} h高度
		 * @return {Panel object}
		 */
		setXY: function( x, y ){
			this._panel.offset({
				top: y,
				left: x
			});
			return this;
		},
		/**
		 * 设置Panel为居中状态
		 *
		 * @method contains
		 */
		center: function(){
			var panelRect = this.getRect(),
				winRect = this.getWinRect(),
				w = panelRect.width,
				h = panelRect.height;
			var x = parseInt( ( winRect.width - w ) / 2 );
			var y = parseInt( ( winRect.height - h ) / 2 );

			if ( x < 0 ) x = 0;
			if ( y < 0 ) y = 0;

			/* if position is 'fixed', x and y coordinate not include bounds coords */
			var position = this._panel.css('position');
			if ( 'fixed' != position ) {
				x = x + winRect.scrollLeft;
				y = y + winRect.scrollTop;
				if ( x <= winRect.scrollLeft ) x = winRect.scrollLeft;
				if ( y <= winRect.scrollTop ) y = winRect.scrollTop;
			}


			this.setXY( x, y );

			return this;
		},
		/**
		 * 判断元素知否包含在Panel之中
		 *
		 * @method contains
		 * @param  {HTMLElement} el
		 * @return {Boolean}
		 */
		contains: function(el) {
			return $.contains( this._panel, el );
		},
		/**
		 * 获取Panel的坐标和大小
		 *
		 * @method getRect
		 * @return {Object}
		 */
		getRect: function(){
			var rlt = this._panel.offset();
			mix( rlt, {
				width: this._panel.width(),
				height: this._panel.height()
			});
			return rlt;
		},
		appendToPanel: function( el ){
			this._panel.append( el );
			return this;
		},
		appendToContent: function( el ){
			this._content.append( el );
			return this;
		},
		getPanel: function(){
			return this._panel;
		},
		getIframe: function(){
			return this._iframe;
		},
		getZIndex: function(){
			//jQuery的css('z-index')是获取计算后的z-index，有奇怪的现象（z-index偶尔变化，FF4.0）
			//return this._panel.css('z-index');
			return this._panel[0].style.zIndex;
		},
		/**
		 * 全屏Panel
		 *
		 * @method setPanelFullscreen
		 * @return {Panel object}
		 */
		setFullscreen: function () {
			var rect = {
				top:	0,
				left:	0,
				height:	$(document).height(),
				width:	$(document).width()
			};
			this.setRect( rect );
			return this;
		},
		addClass: function( className ){
			this._panel.addClass( className );
			if( this._iframe )
				this._iframe.addClass( className );
			return this;
		},
		setStyle: function( name , value ){
			this._panel.css( name, value );
			if( this._iframe )
				this._iframe.css( name, value );
			return this;
		},
		/**
		 * 加元素加入No Blur列表，在此列表中的元素触发的mousedown事件不会导致窗口关闭
		 *
		 * @method addNoBlurList
		 * @param {HTMLElement} el 加入列表的元素
		 * @return {Panel object}
		 */
		addNoBlurList: function( el ){
			if( !el ) return;

			if( el.jquery ){
				el = el[0];
			}

			if( el ){
				this.noBlurList.push( el );
			}
		},
		isPanelShow: function(){
			return this._panel.css('visibility') != 'hidden' && this._panel.css('display') != 'none';
		},
		getWinRect: function(){
			return {
				scrollLeft:	$(window).scrollLeft(),
				scrollTop:	$(window).scrollTop(),
				width:		$(window).width(),
				height:		$(window).height()
			}
		},
		dispose: function(){
			this.fire( 'beforedispose' );
			this._clearPanelEvents();
			this._iframe && this._iframe.remove();
			this._panel && this._panel.remove();
			this.fire( 'afterdispose' );
		}
	});
	return Panel;
});